{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Numpy\n",
    "\n",
    "Numpy is the core library for scientific computing in Python. It provides a high-performance multidimensional array object, and tools for woking with these arrays. "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Array \n",
    "A numpy array is a grid of values, all of the same type, and is indexed by a tuple of nonnegative integers. The number of dimensions is the rank of the array; the shape of an array is a tuple of integers giving the size of the array along each dimension.\n",
    "\n",
    "We can initialize numpy arrays from nested Python liests, and access elements using square brackets:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'numpy.ndarray'>\n",
      "(3,)\n",
      "1 2 3\n",
      "[1 2 3]\n",
      "(2, 3)\n",
      "1 2 4\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    "\n",
    "a  = np.array([1,2,3]) # Create a rank 1 array \n",
    "print(type(a)) \n",
    "print(a.shape)\n",
    "print(a[0],a[1],a[2])\n",
    "print(a)\n",
    "\n",
    "b = np.array([[1,2,3],[4,5,6]])\n",
    "print(b.shape)\n",
    "print(b[0,0],b[0,1],b[1,0])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Numpy also provides many function to create arrays:\n",
    "*You can get more information from the <a href=\"https://docs.scipy.org/doc/numpy/user/basics.creation.html#arrays-creation\"> official doc.</a>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "a is [[0. 0.]\n",
      " [0. 0.]]\n",
      "b is [[1. 1.]]\n",
      "c is [[7 7]\n",
      " [7 7]]\n",
      "d is [[1. 0.]\n",
      " [0. 1.]]\n",
      "e is [[0.48302711 0.32431927]\n",
      " [0.69838647 0.3540748 ]]\n"
     ]
    }
   ],
   "source": [
    "a = np.zeros((2,2)) # an array of all zeros\n",
    "print('a is', a) \n",
    "\n",
    "b = np.ones((1,2)) # crate an array of all ones\n",
    "print('b is', b)\n",
    "\n",
    "c = np.full((2,2,),7) # crate an array of one constant \n",
    "print('c is', c)\n",
    "\n",
    "d = np.eye(2) # a 2 times 2 identity matrix\n",
    "print('d is', d)\n",
    "\n",
    "e = np.random.random((2,2)) # an array with random values\n",
    "print('e is',e)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Array indexing\n",
    "\n",
    "Numpy offers serval ways to index into arrays.\n",
    "**Slicing**: Since Array could be a high-dimensional, we must specify a slice for each dimension of the array."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[ 1  2  3  4]\n",
      " [ 5  6  7  8]\n",
      " [ 9 10 11 12]]\n",
      "\n",
      "\n",
      "[[ 6]\n",
      " [10]]\n",
      "\n",
      "\n",
      "7\n"
     ]
    }
   ],
   "source": [
    "# Create the following rank 2 array with shape (3, 4)\n",
    "# [[ 1  2  3  4]\n",
    "#  [ 5  6  7  8]\n",
    "#  [ 9 10 11 12]]\n",
    "a = np.array([[1,2,3,4],[5,6,7,8],[9,10,11,12]])\n",
    "print(a)\n",
    "print(\"\\n\")\n",
    "b = a[1:3,1:2]\n",
    "print(b)\n",
    "# A slice of an array is a view into the same data, so modifying it\n",
    "# will modify the original array.\n",
    "print(\"\\n\")\n",
    "print(a[1,2]) # before the comma it represents the row; the after one is the column"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Datatypes\n",
    "\n",
    "Every numpy array is a fride of elements of the same type. Numpy provides a large set of numeric datatypes that you can use to construct arrays. Numpy tries to guess a datatype when you create an array, but functions that construct arrays usually also include an optional arguments to explicity specify the datatype. Here is an example: "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "int64\n",
      "float64\n",
      "float64\n"
     ]
    }
   ],
   "source": [
    "# Let numpy choose the datatype\n",
    "x_int64 = np.array([1,2])\n",
    "print(x_int64.dtype) #Prints \"int64\"\n",
    "\n",
    "x_float64 = np.array([1.0,2.0])\n",
    "print(x_float64.dtype) # Prints \"float64\"\n",
    "\n",
    "x_1 = np.array([1,2], dtype = np.float64)\n",
    "print(x_1.dtype)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Array Math \n",
    "\n",
    "We can use array to do the math work, but we can also think about this is matrix's work. Actually, the numpy provide us a way to us matrix.\n",
    "Returns a matrix from an array-like object, or from a string of data $\\dots$ A matrix is a specialized 2-D array that retains its 2-D natrue through operations. \n",
    "**we can replace the `matrix` command by using `array` and the doc. also ask us to replace it**.\n",
    "\n",
    "Actually, in `numpy` we can do a lot of thing with the `array`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "The answer of 'x + y' is \n",
      " [[ 6.  8.]\n",
      " [10. 12.]]\n",
      "The answer of 'x + y' is \n",
      " [[ 6.  8.]\n",
      " [10. 12.]]\n",
      "The answer of 'x - y' is \n",
      " [[-4. -4.]\n",
      " [-4. -4.]]\n",
      "The answer of 'x - y' is \n",
      " [[-4. -4.]\n",
      " [-4. -4.]]\n",
      "The answer of 'x * y' is \n",
      " [[ 5. 12.]\n",
      " [21. 32.]]\n",
      "The answer of 'x * y' is \n",
      " [[ 5. 12.]\n",
      " [21. 32.]]\n",
      "The answer of 'x * y' is \n",
      " [[0.2        0.33333333]\n",
      " [0.42857143 0.5       ]]\n",
      "The answer of 'x * y' is \n",
      " [[0.2        0.33333333]\n",
      " [0.42857143 0.5       ]]\n",
      "The answer of square root of x is \n",
      " [[1.         1.41421356]\n",
      " [1.73205081 2.        ]]\n"
     ]
    }
   ],
   "source": [
    "x = np.array([[1,2],[3,4]], dtype = np.float64)\n",
    "y = np.array([[5,6],[7,8]], dtype = np.float64)\n",
    "\n",
    "# Additon\n",
    "print(\"The answer of 'x + y' is\", \"\\n\", x + y)\n",
    "print(\"The answer of 'x + y' is\", \"\\n\", np.add(x,y))\n",
    "\n",
    "# Sbutraction \n",
    "print(\"The answer of 'x - y' is\", \"\\n\", x - y)\n",
    "print(\"The answer of 'x - y' is\", \"\\n\", np.subtract(x, y))\n",
    "\n",
    "# Multiplication \n",
    "\n",
    "print(\"The answer of 'x * y' is\", \"\\n\", x * y)\n",
    "print(\"The answer of 'x * y' is\", \"\\n\", np.multiply(x, y))\n",
    "\n",
    "# Division\n",
    "print(\"The answer of 'x * y' is\", \"\\n\", x / y)\n",
    "print(\"The answer of 'x * y' is\", \"\\n\", np.divide(x, y))\n",
    "\n",
    "# Square Root\n",
    "print(\"The answer of square root of x is\", \"\\n\", np.sqrt(x))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "For the further infromation check: <a href=\"http://docs.scipy.org/doc/numpy/reference/routines.array-manipulation.html\"> Official Doc.</a>"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.5.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}